<template>
  <a-layout-content
    :style="{
      background: '#fff',
      padding: '24px',
      margin: 0,
      minHeight: '280px',
    }"
    class="layout-content"
  >
    <!-- 订单信息 -->
    <div class="order-info">
      <span>{{ order.date }}</span>
      <span>{{ order.trainCode }}</span
      >次 <span>{{ order.start }}</span
      >站
      <span>({{ order.startTime }})</span>
      <span class="line"></span>
      <span>{{ order.trainCode }}</span>
      <span>{{ order.end }}</span
      >站
      <span>({{ order.endTime }})</span>
    </div>
    <div class="order-ticket">
      <div
        v-for="(item, index) in seatTicket"
        :key="index"
        class="order-ticket-item"
      >
        <span>{{ item.message }}:</span>
        <span class="price">{{ item.price }} ¥</span>
        <span class="count">{{ item.count }}</span
        >张票
      </div>
    </div>
    <a-divider></a-divider>
    <!-- 乘客选择 -->
    <div class="passenger-check">
      <a-checkbox
        :indeterminate="indeterminate"
        :checked="checkAll"
        @change="onCheckAllChange"
        class="check-all"
      >
        全选
      </a-checkbox>
      <a-checkbox-group
        v-model="passengerChecks"
        :options="passengerOptions"
        @change="onChange"
      />
    </div>
    <!-- <div>
      {{ order }}
    </div> -->
    <!-- <div>
      {{ ticketList }}
    </div> -->
    <!-- <div>
      {{ seatTicket }}
    </div> -->
    <div class="order-tickets-container" v-show="ticketList.length">
      <!-- 表格展示 -->
      <div class="order-tickets">
        <a-row class="title" type="flex">
          <a-col :span="6">乘客</a-col>
          <a-col :span="6">身份证</a-col>
          <a-col :span="6">票种</a-col>
          <a-col :span="6">座位类型</a-col>
        </a-row>
        <a-row
          class="content"
          v-for="(item, index) in ticketList"
          :key="index"
          type="flex"
        >
          <a-col :span="6">{{ item.passengerName }}</a-col>
          <a-col :span="6">{{ item.passengerIdCard }}</a-col>
          <a-col :span="6">
            <a-select
              v-model="item.passengerType"
              style="width: 100px"
              :default-value="item.passengerType"
            >
              <a-select-option
                v-for="(passenger, index) in passengerTypeArray"
                :key="index"
                :value="passenger.code"
              >
                {{ passenger.message }}
              </a-select-option>
            </a-select>
          </a-col>
          <a-col :span="6">
            <a-select
              v-model="item.seatTypeCode"
              style="width: 100px"
              :default-value="item.seatTypeCode"
            >
              <a-select-option
                v-for="(seat, index) in seatTypeArray"
                :key="index"
                :value="seat.code"
              >
                {{ seat.message }}
              </a-select-option>
            </a-select>
          </a-col>
        </a-row>
      </div>
      <div>
        <a-space>
          <!-- 查看购票按钮 -->
          <a-button type="primary" @click="openQueryWaitingStatus"
            >查看购票</a-button
          >
          <!-- 提交订单按钮 -->
          <a-button
            type="primary"
            @click="openOrderTicketModel"
            style="margin-right: 0px"
            >提交订单
          </a-button>
        </a-space>
      </div>
    </div>
    <!-- 订单确认窗口 -->
    <a-modal
      v-model="visible"
      title="请核对以下信息"
      @ok="confirmOrder"
      :centered="true"
      ok-text="确认"
      cancel-text="取消"
    >
      <!-- 乘客选座信息 -->
      <div class="order-tickets-model">
        <a-row class="title" type="flex">
          <a-col :span="6">乘客</a-col>
          <a-col :span="6">身份证</a-col>
          <a-col :span="6">票种</a-col>
          <a-col :span="6">座位类型</a-col>
        </a-row>
        <a-row
          class="content"
          v-for="(item, index) in ticketList"
          :key="index"
          type="flex"
        >
          <a-col :span="6">{{ item.passengerName }}</a-col>
          <a-col :span="6">{{ item.passengerIdCard }}</a-col>
          <a-col :span="6">
            <span v-for="(passenger, index) in passengerTypeArray" :key="index">
              <span v-if="passenger.code === item.passengerType">{{
                passenger.message
              }}</span>
            </span>
          </a-col>
          <a-col :span="6">
            <span v-for="(seat, index) in seatTypeArray" :key="index">
              <span v-if="seat.code === item.seatTypeCode">{{
                seat.message
              }}</span>
            </span>
          </a-col>
        </a-row>
      </div>
      <!-- 选座按钮 -->
      <div class="choose-seat">
        <div v-if="chooseSeatType === 0" style="color: red">
          <span>您购买的车票不支持选座</span>
          <span>12306规定: 只有全部是一等座或二等座的时候支持选座</span>
          <span>12306规定: 余票小于20的时候不支持选座</span>
        </div>
        <div v-else>
          <div class="choose-seat-row">
            <a-space
              class="choose-seat-col"
              v-for="seat in seatColArray"
              :key="seat.code + 1"
            >
              <span>{{ seat.code + 1 }}</span>
              <a-switch v-model="chooseSeat[seat.code + 1]" />
            </a-space>
          </div>
          <div v-if="ticketList.length > 1" class="choose-seat-row">
            <a-space
              class="choose-seat-col"
              v-for="seat in seatColArray"
              :key="seat.code + 2"
            >
              <span>{{ seat.code + 2 }}</span>
              <a-switch v-model="chooseSeat[seat.code + 2]" />
            </a-space>
          </div>
          <div style="color: #999999; margin-top: 5px" class="choose-seat-row">
            提示:您可以选择{{ ticketList.length }}个座位
          </div>
        </div>
      </div>
    </a-modal>
    <!-- 验证码窗口 -->
    <a-modal
      v-model="captchaModalVisible"
      title="请输入验证码"
      @ok="submitOrder"
      :centered="true"
      ok-text="确认"
      cancel-text="取消"
      @cancel="inputCaptcha = ''"
    >
      <div class="captcha">
        <a-input
          v-model="inputCaptcha"
          placeholder="请输入验证码"
          style="width: 200px"
        />
        <img class="captchaImage" :src="captchaImage" @click="getCaptcha" />
      </div>
    </a-modal>
    <!-- 等待提示窗口 -->
    <a-modal
      v-model="awaitModalVisible"
      :mask="true"
      :width="200"
      @cancel="stopInterval(false)"
      v-show="waitingStatus !== null"
    >
      <div v-if="waitingStatus === '0'" style="font-weight: bolder">
        系统正在处理中...
      </div>
      <div style="font-weight: bolder" v-else>
        <a-spin>
          <a-icon
            slot="indicator"
            type="loading"
            style="font-size: 24px"
            spin
          />
        </a-spin>
        {{ `系统处理中, 预计还需等待${waitingStatus}人, 请耐心等待...` }}
      </div>
      <template slot="footer">
        <a-button type="danger" @click.stop="() => cancelOrder()"
          >取消确认订单</a-button
        >
      </template>
    </a-modal>
  </a-layout-content>
</template>

<script>
import { getSession, SESSION_ORDER } from "@/utils/session";
import { list } from "@/api/passenger";
import { notification } from "ant-design-vue";
import "ant-design-vue/lib/notification/style/css";
import {
  confirmTicket,
  getCaptcha,
  getOrderStatus,
  cancelConfirmOrder,
} from "@/api/order";
import { v4 as uuidv4 } from "uuid";

export default {
  data() {
    return {
      order: {}, // 订单信息
      seatTicket: [], // 座位票信息
      passengerOptions: [], // 乘客列表
      passengerChecks: [], //选中的乘客
      ticketList: [], // 乘客购票列表
      chooseSeatType: 0, //乘客可选座位类型 0不可选, 1一等座, 2二等座
      chooseSeat: {}, //构造乘客选座对象, 用于请求参数处理
      indeterminate: true,
      checkAll: false,
      visible: false,
      captchaModalVisible: false,
      captchaImage: "",
      inputCaptcha: "",
      captchaToken: "",
      awaitModalVisible: false,
      waitingStatus: null,
      timer: null,
      orderId: null,
      oldNum: 0,
    };
  },
  computed: {
    seatType() {
      return window.SEAT_TYPE;
    },
    seatTypeArray() {
      return window.SEAT_TYPE_ARRAY;
    },
    passengerTypeArray() {
      return window.PASSENGER_TYPE_ARRAY;
    },
    //选座数组,用于操作界面渲染和选座请求参数构造
    seatColArray() {
      return window.SEAT_COL_ARRAY.filter(
        (item) => item.type === this.chooseSeatType
      );
    },
  },
  created() {
    this.getPassengerList();
  },
  mounted() {
    this.order = getSession(SESSION_ORDER) || {};
    this.getSeatTicket();
  },
  watch: {
    passengerChecks: {
      deep: true,
      handler(newValue) {
        this.ticketList = [];
        this.passengerChecks.forEach((checkedId) => {
          newValue.forEach((item) => {
            if (item === checkedId) {
              this.passengerOptions.map((passenger) => {
                if (passenger.value === checkedId) {
                  this.ticketList.push({
                    passengerId: passenger.item.id,
                    passengerType: passenger.item.type,
                    seatTypeCode: this.seatTicket[0].code,
                    passengerName: passenger.item.name,
                    passengerIdCard: passenger.item.idCard,
                  });
                }
              });
            }
          });
        });
      },
    },
    //当chooseSeatType变化的时候,重新构造2排选座对象, 用于请求参数处理
    seatColArray(seatTypeList) {
      this.chooseSeat = {};
      for (let i = 1; i <= 2; i++) {
        seatTypeList.forEach((seatType) => {
          this.$set(this.chooseSeat, seatType.code + i, false); //响应式赋值
        });
      }
    },
  },
  methods: {
    getSeatTicket() {
      for (const KEY in this.seatType) {
        const key = KEY.toLocaleLowerCase();
        if (this.order[key] >= 0) {
          this.seatTicket.push({
            type: key,
            code: this.seatType[KEY]["code"],
            message: this.seatType[KEY]["message"],
            count: this.order[key],
            price: this.order[key + "Price"],
          });
        }
      }
    },
    async getPassengerList() {
      if (this.passengerOptions.length === 0) {
        list().then((res) => {
          if (res.code === 200) {
            this.passengerOptions = res.data.map((item) => {
              return {
                label: item.name,
                value: item.id,
                item: item,
              };
            });
          }
        });
      }
    },
    onChange(passengerChecks) {
      this.indeterminate =
        !!passengerChecks.length &&
        passengerChecks.length < this.passengerOptions.length;
      this.checkAll = passengerChecks.length === this.passengerOptions.length;
    },
    onCheckAllChange(e) {
      Object.assign(this, {
        passengerChecks: e.target.checked
          ? this.passengerOptions.map((option) => option.value)
          : [],
        indeterminate: false,
        checkAll: e.target.checked,
      });
    },
    confirmOrder(e) {
      //选座以后为提交的乘客订单赋值seat属性,校验选座和购票是否一致
      for (let ticket of this.ticketList) {
        ticket.seat = null;
      }
      let i = -1;
      for (let seat in this.chooseSeat) {
        if (this.chooseSeat[seat]) {
          i++;
          if (i > this.ticketList.length - 1) {
            notification.error({
              title: "消息提示",
              duration: 2,
              message: "选座数量不能大于所选乘客",
            });
            return;
          }
          this.ticketList[i].seat = seat; //从0开始顺序赋值
        }
      }

      if (i > -1 && i < this.ticketList.length - 1) {
        notification.error({
          title: "消息提示",
          duration: 2,
          message: "选座数量不足,请继续添加",
        });
        return;
      }

      //请求获取验证码
      this.getCaptcha();
    },
    openOrderTicketModel() {
      //校验票数是否大于5张
      if (this.ticketList.length > 5) {
        notification.error({
          title: "消息提示",
          duration: 2,
          message: "最多只能购买5张票",
        });
        return;
      }

      //预扣票数,校验余票
      for (let i = 0; i < this.seatTicket.length; i++) {
        let seatTmp = { ...this.seatTicket[i] };
        for (let j = 0; j < this.ticketList.length; j++) {
          if (this.ticketList[j].seatTypeCode === seatTmp.code) {
            seatTmp.count--;
            if (seatTmp.count < 0) {
              notification.error({
                title: "消息提示",
                duration: 2,
                message: "余票不足",
              });
              return;
            }
          }
        }
      }

      //判断是否支持选座,并生成选座类型变量
      const seatTypeCodeArr = []; //座位类型code集合
      for (let i = 0; i < this.ticketList.length; i++) {
        seatTypeCodeArr.push(this.ticketList[i].seatTypeCode);
      }
      const seatTypeCodeSet = Array.from(new Set(seatTypeCodeArr));
      if (seatTypeCodeSet.length !== 1) {
        //同时购买两种或以上,不可选座
        this.chooseSeatType = 0;
      } else {
        if (seatTypeCodeSet[0] === this.seatType.YDZ.code) {
          this.chooseSeatType = this.seatType.YDZ.code;
        } else if (seatTypeCodeSet[0] === this.seatType.EDZ.code) {
          this.chooseSeatType = this.seatType.EDZ.code;
        } else {
          this.chooseSeatType = 0;
        }

        //判断对应座位类型的余票是否小于20, 小于则不能选座
        if (this.chooseSeatType !== 0) {
          this.seatTicket.forEach((seat) => {
            if (seat.code === seatTypeCodeSet[0]) {
              if (seat.count < 20) {
                this.chooseSeatType = 0;
              }
            }
          });
        }
      }

      this.visible = true;
    },
    async getCaptcha() {
      //生成token
      this.captchaToken = uuidv4();
      await getCaptcha(this.captchaToken).then((res) => {
        if (res.code === 200) {
          this.captchaImage = "data:image/png;base64," + res.data.captchaBase64;
          this.captchaModalVisible = true;
        }
      });
      this.visible = false;
    },
    //提交确认订单
    submitOrder() {
      //校验验证码
      const captcha = this.inputCaptcha;
      if (captcha === "") {
        notification.error({
          title: "消息提示",
          duration: 2,
          message: "验证码不能为空",
        });
        return;
      }
      //发起请求,确认订单
      confirmTicket(
        this.order,
        this.ticketList,
        captcha,
        this.captchaToken
      ).then((res) => {
        if (res.code === 200) {
          this.orderId = res.data;
          notification.success({
            title: "消息提示",
            duration: 2,
            message: "确认订单提交成功",
          });
          this.intervalQueryWaitingStatus(this.orderId);
        }
      });
      this.inputCaptcha = "";
      this.waitingStatus = "0";
      this.captchaModalVisible = false;
      this.awaitModalVisible = true;
    },
    //定时查询订单等待状态
    intervalQueryWaitingStatus(orderId) {
      this.queryWaitingStatus(orderId); //立刻执行一次
      this.timer = setInterval(() => {
        this.queryWaitingStatus(orderId);
      }, 9000);
    },
    //查询订单等待状态
    queryWaitingStatus(orderId) {
      getOrderStatus(orderId).then((res) => {
        if (res.code === 200) {
          if (
            res.data.code != null &&
            res.data.code !== undefined &&
            res.data.code === 500
          ) {
            this.stopInterval(true);
          } else {
            switch (res.data) {
              case "-1":
                notification.success({
                  title: "消息提示",
                  duration: 2,
                  message: "购票成功",
                });
                this.stopInterval(true);
                break;
              case "-3":
                notification.error({
                  title: "消息提示",
                  duration: 2,
                  message: "购票失败",
                });
                this.stopInterval(true);
                break;
              case "-4":
                notification.info({
                  title: "消息提示",
                  duration: 2,
                  message: "余票不足",
                });
                this.stopInterval(true);
                break;
              default:
                this.waitingStatus = res.data;
                break;
            }
          }
        } else {
          this.stopInterval(true);
        }
      });
    },
    //停止定时轮训查看请求订单状态
    stopInterval(isClearOrderId) {
      clearInterval(this.timer);
      this.timer = null;
      this.waitingStatus = null;
      this.awaitModalVisible = false;
      if (isClearOrderId) {
        this.orderId = null;
      }
      console.log("定时器清除");
    },
    //点击按钮查看订单状态
    openQueryWaitingStatus() {
      if (this.orderId === null) {
        notification.error({
          title: "消息提示",
          duration: 2,
          message: "无提交订单",
        });
        return;
      }
      this.awaitModalVisible = true;
      this.intervalQueryWaitingStatus(this.orderId);
    },
    //取消订单确认
    cancelOrder() {
      cancelConfirmOrder(this.orderId).then((res) => {
        if (res.code === 200) {
          notification.success({
            title: "消息提示",
            duration: 2,
            message: "取消订单成功",
          });
          this.stopInterval(true);
        } else {
          notification.error({
            title: "消息提示",
            duration: 2,
            message: res.message || "取消订单失败",
          });
        }
      });
    },
  },
};
</script>

<style lang="less" scoped>
.layout-content {
  .order-info {
    width: 100%;
    text-align: center;
    margin-top: 20px;
    font-size: 18px;
    span {
      margin-left: 10px;
      font-weight: bolder;
    }
    .line {
      display: inline-block;
      border: 0.5px solid #858585;
      width: 3%;
      margin-bottom: 5px;
    }
  }
  .order-ticket {
    width: 100%;
    display: flex;
    justify-content: center;
    margin-top: 10px;
    font-size: 15px;
    //让两个order-ticket-item往中间的距离缩短
    .order-ticket-item {
      margin: 0 30px; /* 调整这里的间距 */
      span {
        margin: 0 5px;
      }
      .price,
      .count {
        font-weight: bolder;
        color: red;
      }
    }
  }
  .passenger-check {
    margin-left: 20px;
    .check-all {
      margin-right: 10px;
    }
  }
  .order-tickets-container {
    margin-top: 20px !important;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    width: 650px;
    margin: 0 auto;
    .order-tickets {
      width: 650px;
      border: 1px solid rgb(62, 159, 255);
      max-height: 300px;
      overflow-y: auto;
      background-color: #f9f9f9;
      .title {
        height: 50px;
        text-align: center;
        align-items: center;
        background-color: rgb(62, 159, 255);
        color: rgb(255, 255, 255);
        position: sticky;
        top: 0; /* 固定在顶部 */
        z-index: 10; /* 确保标题在内容上方 */
      }
      .content {
        height: 50px;
        text-align: center;
        align-items: center;
      }
    }
    .ant-btn-primary {
      margin-top: 10px;
    }
  }
}
/deep/ .ant-modal {
  width: 680px !important;
  .order-tickets-model {
    max-height: 350px;
    overflow-y: auto;
    .title {
      height: 50px;
      text-align: center;
      align-items: center;
      background-color: rgb(62, 159, 255);
      color: rgb(255, 255, 255);
      position: sticky;
      top: 0; /* 固定在顶部 */
      z-index: 10; /* 确保标题在内容上方 */
    }
    .content {
      height: 50px;
      text-align: center;
      align-items: center;
      border: 1px solid rgb(62, 159, 255);
      border-top: none;
    }
  }
  .choose-seat {
    span {
      display: flex; /* 使用 flexbox 进行排列 */
      flex-direction: column; /* 纵向排列 */
    }
    .choose-seat-col {
      margin: 20px 5px 0 5px;
    }
    .choose-seat-row {
      display: flex;
      justify-content: center;
    }
  }
  .captcha {
    text-align: center;
    .captchaImage {
      width: 100px; // 根据需要调整图片宽度
      height: 32px; // 根据需要调整图片高度
      margin-bottom: 2.5px;
      cursor: pointer;
    }
  }
}
</style>
